package com.realtyreg.webview.controller;

import net.tanesha.recaptcha.ReCaptcha;
import net.tanesha.recaptcha.ReCaptchaResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;
import com.realtyreg.common.exception.BusinessException;
import com.realtyreg.common.exception.ResourceNotFoundException;
import com.realtyreg.domain.entity.users.User;
import com.realtyreg.domain.entity.users.UserRole;
import com.realtyreg.service.UserService;
import com.realtyreg.service.form.NameForm;
import com.realtyreg.service.form.Registration;
import com.realtyreg.service.validator.NameValidator;
import com.realtyreg.webview.message.MessageSaver;
import com.realtyreg.webview.message.MessageType;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Locale;

/**
 * Created by Petro 22.12.12 23:30
 */
@Controller
@RequestMapping("/register")
public class RegisterController {
    private static final Logger LOG = Logger.getLogger(RegisterController.class);
    private static final String MA_RECAPTCHA_HTML = "reCaptchaHtml";

    @Autowired
    private UserService userService;
    @Autowired
    private NameValidator nameValidator;
    @Autowired
    private ReCaptcha reCaptcha;
    @Autowired
    private MessageSaver messageSaver;

    //регистрация GET
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String registerForm(Model model) {
        Registration registration = new Registration();
        registration.setRole(UserRole.INDIVIDUAL.name());
        model.addAttribute(registration);
        String html = reCaptcha.createRecaptchaHtml(null, "white", null);
        model.addAttribute(MA_RECAPTCHA_HTML, html);
        return "register";
    }

    //регистрация POST
    @RequestMapping(value = "", method = RequestMethod.POST)
    public String register(@Valid @ModelAttribute Registration registration, BindingResult result, SessionStatus status, HttpServletRequest req, Model model, Locale locale,
                           @RequestParam("recaptcha_challenge_field") String challenge,
                           @RequestParam("recaptcha_response_field") String response) {
        if (StringUtils.isNotEmpty(registration.getRole())) {
            NameForm nameForm = registration.getNameForm();
            nameForm.setRole(registration.getRole());
            nameForm.setPathPrefix("nameForm.");
            nameValidator.validate(nameForm, result);
        }

        ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(req.getRemoteAddr(), challenge, response);
        if (!reCaptchaResponse.isValid())
            result.reject("validation.registration.badCaptcha");
        else if (userService.userExists(registration.getEmail()))
            result.reject("validation.registration.userExists");

        String html = reCaptcha.createRecaptchaHtml(null, "white", null);
        model.addAttribute(MA_RECAPTCHA_HTML, html);

        if (result.hasErrors())
            return "register";

        User user = userService.create(registration);
        status.setComplete();
        LOG.info(String.format("Пользователь зарегистрирован %s", user));
        messageSaver.saveMessage(model, MessageType.SUCCESS, "registration.success", locale);
        return "registerSuccess";
    }

    //подтверждение регистрации
    @RequestMapping(value = "/confirm/{id}/{token}", method = RequestMethod.GET)
    public String registerConfirm(@PathVariable Long id, @PathVariable String token, Model model, Locale locale) {
        User user = userService.findOne(id);
        if (user == null) {
            throw new ResourceNotFoundException(String.format("Пользователь id=%s не найден", id));
        }

        String confirmToken = user.getConfirmToken();
        if (user.isConfirmed() || StringUtils.isEmpty(confirmToken)) {
            LOG.error(String.format("Пользователь %s уже подтвердил регистрацию", user));
            messageSaver.saveMessage(model, MessageType.ERROR, "registration.confirm.already", locale);
        }
        else {
            boolean tokensEquals = confirmToken.equals(token);
            if (tokensEquals) {
                user.setConfirmed(true);
                user.setConfirmToken(null);
                userService.save(user);
                LOG.info(String.format("Пользователь %s успешно подтвердил регистрацию", user));
                messageSaver.saveMessage(model, MessageType.SUCCESS, "registration.confirm.success", locale);
            }
            else {
                throw new BusinessException(String.format("Ошибка при подтверждении регистрации: токены не совпадают. Пользователь %s, ожидается токен '%s', пришел '%s'.", user, confirmToken, token));
            }
        }
        return "registerConfirm";
    }
}
